package org.sun.sunshine.io.cun;
import com.google.common.util.concurrent.*;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
public class GuavaFutureDemo {
    public static final int SLEEP_GAP = 500;
    public static String getCurThreadName() {
        return Thread.currentThread().getName();
    }
    //业务逻辑：烧水
    static class HotWarterJob implements Callable<Boolean>
    {
        @Override
        public Boolean call() throws Exception
        {
            //……省略，与使用FutureTask实现异步泡茶喝相同
            return true;
        }
    }
    //业务逻辑：清洗
    static class WashJob implements Callable<Boolean> {
        @Override
        public Boolean call() throws Exception {
            //……省略，与使用FutureTask实现异步泡茶喝相同
            return false;
        }
    }
    //新创建一个异步业务类型，作为泡茶喝主线程类
    static class MainJob implements Runnable {
        boolean warterOk = false;
        boolean cupOk = false;
        int gap = SLEEP_GAP / 10;
        @Override
        public void run() {
            while (true) {
                try {
                    Thread.sleep(gap);
                    log.info("读书中......");
                } catch (InterruptedException e) {
                    log.info(getCurThreadName() + "发生异常被中断.");
                }
                if (warterOk||cupOk) {
                    drinkTea(warterOk, cupOk);
                }
            }
        }
        public void drinkTea(Boolean wOk, Boolean cOK) {
            if (wOk&&cOK) {
                log.info("泡茶喝，茶喝完");
                this.warterOk = false;
                this.gap = SLEEP_GAP * 100;
            } else if (!wOk) {
                log.info("烧水失败，没有茶喝了");
            } else if (!cOK) {
                log.info("杯子洗不了，没有茶喝了");
            }
        }
    }
    public static void main(String args[]) {
        //创建一个新的线程实例，作为泡茶主线程
        MainJob mainJob = new MainJob();
        Thread mainThread = new Thread(mainJob);
        mainThread.setName("主线程");
        mainThread.start();
        //烧水的业务逻辑实例
        Callable<Boolean>hotJob = new HotWarterJob();
        //清洗的业务逻辑实例
        Callable<Boolean>washJob = new WashJob();
        //创建Java 线程池
        ExecutorService jPool = Executors.newFixedThreadPool(10);

        //包装Java线程池，构造Guava 线程池
        ListeningExecutorService gPool
                = MoreExecutors.listeningDecorator(jPool);

        //提交烧水的业务逻辑实例，到Guava线程池获取异步任务
        ListenableFuture<Boolean> hotFuture = gPool.submit(hotJob);

        //绑定异步回调，烧水完成后，把喝水任务的warterOk标志设置为true
        Futures.addCallback(hotFuture, new FutureCallback<Boolean>() {
            public void onSuccess(Boolean r) {
                if (r) {
                    mainJob.warterOk = true;
                }
            }
            public void onFailure(Throwable t) {
                log.info("烧水失败，没有茶喝了");
            }
        },gPool);
        //提交清洗的业务逻辑实例，到Guava线程池获取异步任务
        //ListenableFuture    可以添加一个callback 当线程完成后，自动执行回调，这样主线程就不用阻塞了。
        ListenableFuture<Boolean> washFuture = gPool.submit(washJob);
        //绑定任务执行完成后的回调逻辑到异步任务
        Futures.addCallback(washFuture, new FutureCallback<Boolean>() {
            public void onSuccess(Boolean r) {
                if (r) {
                    mainJob.cupOk = true;
                }
            }
            public void onFailure(Throwable t) {
                log.info("杯子洗不了，没有茶喝了");
            }
        },gPool);
    }
}